﻿/*
 * @author: wizardc
 */

using System;
using System.Collections.Generic;
using UnityEngine;

namespace DouEditor.Extend
{
    /// <summary>
    /// Editor非运行模式下快捷查看Animator的工具组件，支持选择State播放和速率调整
    /// 注意：不同层的相同名称状态会被归类一起播放
    /// </summary>
    [RequireComponent(typeof(Animator))]
    [DisallowMultipleComponent]
    [ExecuteInEditMode]
    public class AnimatorQuickViewer : MonoBehaviour
    {
        public Animator animator;
        public List<AnimationEditorClipInfo> clips;
        [NonSerialized]
        public List<string> animationNameList;

        private AnimationEditorData _animationEditorData;

        [SerializeField]
        private int _frameRate = 30;
        private float _frameTime = 1f / 30;

        private AnimatorEditorPlayInfo _animatorEditorPlayInfo;

        private AnimatorEditorPlayInfo AnimatorEditorPlayInfo
        {
            get
            {
                if (_animatorEditorPlayInfo == null)
                {
                    CollectAnimationData();
                    _animatorEditorPlayInfo = AnimatorEditorPlayMgr.instance.AddData(_animationEditorData);
                }
                return _animatorEditorPlayInfo;
            }
        }

        public bool playing
        {
            get
            {
                if (AnimatorEditorPlayInfo != null)
                {
                    return AnimatorEditorPlayInfo.playing;
                }
                return false;
            }
        }

        public double currentTime
        {
            set
            {
                if (AnimatorEditorPlayInfo != null)
                {
                    AnimatorEditorPlayInfo.currentTime = value;
                }
            }
            get
            {
                if (AnimatorEditorPlayInfo != null)
                {
                    return AnimatorEditorPlayInfo.currentTime;
                }
                return 0;
            }
        }

        public double totalTime
        {
            get
            {
                if (AnimatorEditorPlayInfo != null)
                {
                    return AnimatorEditorPlayInfo.totalTime;
                }
                return 0;
            }
        }

        public int frameRate
        {
            set
            {
                _frameRate = value;
                _frameTime = 1f / _frameRate;
            }
            get => _frameRate;
        }

        public int currentFrame
        {
            set
            {
                if (totalTime > 0)
                {
                    currentTime = ((float) value / (float) totalFrame) * totalTime;
                }
            }
            get
            {
                if (totalTime == 0)
                {
                    return 0;
                }
                return Mathf.FloorToInt((float) currentTime / (float) totalTime * totalFrame);
            }
        }

        public int totalFrame
        {
            get
            {
                if (totalTime == 0)
                {
                    return 0;
                }
                return Mathf.CeilToInt((float) totalTime / _frameTime);
            }
        }

        public bool isLoop
        {
            set
            {
                if (AnimatorEditorPlayInfo != null)
                {
                    AnimatorEditorPlayInfo.isLoop = value;
                }
            }
            get
            {
                if (AnimatorEditorPlayInfo != null)
                {
                    return AnimatorEditorPlayInfo.isLoop;
                }
                return false;
            }
        }

        public float ratio
        {
            set
            {
                if (AnimatorEditorPlayInfo != null)
                {
                    AnimatorEditorPlayInfo.ratio = value;
                }
            }
            get
            {
                if (AnimatorEditorPlayInfo != null)
                {
                    return AnimatorEditorPlayInfo.ratio;
                }
                return 1;
            }
        }

        private void CollectAnimationData()
        {
            animator = GetComponent<Animator>();
            _animationEditorData = AnimationEditorData.Collect(animator);
            clips = _animationEditorData.clips;
            animationNameList = new List<string>();
            foreach (var info in clips)
            {
                if (!animationNameList.Contains(info.name))
                {
                    animationNameList.Add(info.name);
                }
            }
        }

        /// <param name="name">为空时播放默认状态</param>
        public void Play(string name = null)
        {
            AnimatorEditorPlayInfo.Play(name);
        }

        public void Pause()
        {
            AnimatorEditorPlayInfo.Pause();
        }

        public void Resume()
        {
            AnimatorEditorPlayInfo.Resume();
        }

        public void Stop()
        {
            AnimatorEditorPlayInfo.Stop();
        }

        private void OnDestroy()
        {
            AnimatorEditorPlayMgr.instance.RemoveData(_animationEditorData);
        }
    }
}
